<template>
  <div ref="drag" class="drag-box" @mousedown="mouseDown">
    <slot />
  </div>
</template>
<script>
export default {
  name: 'Drag',
  props: {
    site: {
      type: Object,
      default: () => ({
        right: 0,
        bottom: 0
      })
    }
  },
  data() {
    return {
      left: 0,
      top: 0,
      flat: 0
    };
  },
  mounted() {
    this.left = this.$refs.drag.parentElement.clientWidth;
    this.top = this.$refs.drag.parentElement.clientHeight;
    window.addEventListener('resize', this.Resize);
  },

  beforeUpdate() {
    if (!this.flat) {
      Object.getOwnPropertyNames(this.$props.site).forEach(key => {
        if (key === 'left') {
          this.$refs.drag.style.left = `${this.$props.site[key]}px`;
        } else if (key === 'right') {
          this.$refs.drag.style.left = `${this.$refs.drag.parentElement
            .clientWidth -
            this.$refs.drag.scrollWidth -
            this.$props.site[key]}px`;
          this.flat = this.$refs.drag.scrollWidth;
        } else if (key === 'top') {
          this.$refs.drag.style.top = `${this.$props.site[key]}px`;
        } else if (key === 'bottom') {
          this.$refs.drag.style.top = `${this.$refs.drag.parentElement
            .clientHeight -
            this.$refs.drag.scrollHeight -
            this.$props.site[key]}px`;
        }
      });
    }
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.Resize);
  },
  methods: {
    Resize() {
      this.$refs.drag.style.left = `${this.$refs.drag.offsetLeft -
        (this.left - this.$refs.drag.parentElement.clientWidth)}px`;
      this.$refs.drag.style.top = `${this.$refs.drag.offsetTop -
        (this.top - this.$refs.drag.parentElement.clientHeight)}px`;

      this.left = this.$refs.drag.parentElement.clientWidth;
      this.top = this.$refs.drag.parentElement.clientHeight;
    },
    mouseDown(e) {
      const dragBox = this.$refs.drag; // 获取当前元素
      e.preventDefault();
      // 算出鼠标相对元素的位置
      const disX = e.clientX - dragBox.offsetLeft;
      const disY = e.clientY - dragBox.offsetTop;
      document.onmousemove = e1 => {
        // 用鼠标的位置减去鼠标相对元素的位置，得到元素的位置
        e.preventDefault();
        const left = e1.clientX - disX;
        const top = e1.clientY - disY;
        // 移动当前元素
        if (left >= 0) {
          dragBox.style.left = `${
            left >= dragBox.parentElement.clientWidth - dragBox.scrollWidth
              ? dragBox.parentElement.clientWidth - dragBox.scrollWidth
              : left
          }px`;
        } else {
          dragBox.style.left = `${left <= 0 ? 0 : left}px`;
        }
        if (top >= 0) {
          dragBox.style.top = `${
            top >= dragBox.parentElement.clientHeight - dragBox.scrollHeight
              ? dragBox.parentElement.clientHeight - dragBox.scrollHeight
              : top
          }px`;
        } else {
          dragBox.style.top = `${top <= 0 ? 0 : top}px`;
        }
      };
      document.onmouseup = e2 => {
        e2.preventDefault();
        // 鼠标弹起来的时候不再移动
        document.onmousemove = null;
        // 预防鼠标弹起来后还会循环
        document.onmouseup = null;
      };
    }
  }
};
</script>
<style lang="less">
.drag-box {
  position: absolute;
  z-index: 100;
  cursor: pointer;
  > div {
    position: absolute;
  }
}
</style>
